package com.kamistoat.meimeistore.member.web;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kamistoat.common.To.MemberReceiveAddressTo;
import com.kamistoat.common.constant.MemberConstant;
import com.kamistoat.common.exception.BizCodeEnum;
import com.kamistoat.common.runTimeFunc.RunTimeLog;
import com.kamistoat.common.utils.R;
import com.kamistoat.meimeistore.member.dao.MemberReceiveAddressDao;
import com.kamistoat.meimeistore.member.entity.MemberEntity;
import com.kamistoat.meimeistore.member.entity.MemberReceiveAddressEntity;
import com.kamistoat.meimeistore.member.feign.ThirdFeignService;
import com.kamistoat.meimeistore.member.interceptor.LoginInterceptor;
import com.kamistoat.meimeistore.member.service.MemberReceiveAddressService;
import com.kamistoat.meimeistore.member.service.MemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

@Controller
public class MemberWebController {

    @Autowired
    MemberService memberService;
    @Autowired
    MemberReceiveAddressService memberReceiveAddressService;
    @Autowired
    MemberReceiveAddressDao memberReceiveAddressDao;

    @Autowired
    ThirdFeignService thirdFeignService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 跳转到用户信息页面
     *
     * @param model
     * @return
     */
    @GetMapping("/web/info.html")
    public String infoPage(Model model) {
        MemberEntity member = memberService.getById(LoginInterceptor.loginUserThreadLocal.get().getId());
        member.setPassword("");
        model.addAttribute("member", member);
        return "info";
    }


    /**
     * 跳转到修改密码页面
     *
     * @param model
     * @return
     */
    @GetMapping("/web/secret.html")
    public String secretPage(Model model) {
        Long memberId = LoginInterceptor.loginUserThreadLocal.get().getId();
        model.addAttribute("memberId", memberId);
        return "secret";
    }

    /**
     * 跳转到地址页面
     *
     * @param model
     * @return
     */
    @GetMapping("/web/address.html")
    public String addressPage(Model model) {
        Long memberId = LoginInterceptor.loginUserThreadLocal.get().getId();
        // 默认地址在前。因此直接用Desc排序即可
        List<MemberReceiveAddressEntity> addressList =
                memberReceiveAddressService.list(new QueryWrapper<MemberReceiveAddressEntity>().
                        eq("member_id", memberId).
                        orderByDesc("default_status"));
        model.addAttribute("addressList", addressList);
        return "address";
    }


    /**
     * 接口。修改基础信息
     *
     * @param id
     * @param nickname
     * @param gender
     * @return
     */
    @ResponseBody
    @GetMapping("/web/updateinfo")
    public R updateInfo(@RequestParam Long id, @RequestParam String nickname, @RequestParam Integer gender) {
        MemberEntity member = memberService.getById(id);
        member.setNickname(nickname);
        member.setGender(gender);
        memberService.updateById(member);
        RunTimeLog.printRunTimeLog(id + "号用户将昵称更改为" + nickname + "，性别更改为" + gender);
        return R.ok();
    }

    /**
     * 接口。修改密码时发送短信验证身份
     *
     * @param phoneNum
     * @return
     */
    @ResponseBody
    @GetMapping("/web/sendcodepassword")
    public R sendCode_Password(@RequestParam String phoneNum) {
        if (StringUtils.isEmpty(phoneNum)) {
            return R.error(1, "请先输入有效手机号");
        }
        // 先看看redis中是否已经存在一个同手机号的验证码
        String oldCode = stringRedisTemplate.opsForValue().get(MemberConstant.SMS_CODE_CACHE_PREFIX + phoneNum);
        if (!StringUtils.isEmpty(oldCode)) {
            // 如果已经存在，把这个验证码的时间拿出来
            Long oldTime = Long.parseLong(oldCode.split("_")[1]);
            if (System.currentTimeMillis() - oldTime < 60000) {
                // 如果是在60秒内重复发送验证码，就不准再发
                return R.error(BizCodeEnum.SMS_REPEAT_EXCEPTION.getCode(), BizCodeEnum.SMS_REPEAT_EXCEPTION.getMessage());
            }
        }
        // 生成验证码
        String code = UUID.randomUUID().toString().substring(0, 5);
        // redis存放值，key就是 sms:code:手机号，值就是验证码_当前系统时间
        stringRedisTemplate.opsForValue().set(
                MemberConstant.SMS_CODE_CACHE_PREFIX + phoneNum,
                code + "_" + System.currentTimeMillis(),
                MemberConstant.SMS_CODE_EXPIRE_TIME,
                MemberConstant.SMS_CODE_EXPIRE_UNIT);

        thirdFeignService.sendSMSCode_Password(
                phoneNum, code, MemberConstant.SMS_CODE_EXPIRE_TIME);
        return R.ok();
    }

    /**
     * 检查验证码是否正确。
     *
     * @param phoneNum
     * @return
     */
    @ResponseBody
    @GetMapping("/web/checkUpdateSecretCode")
    public R checkUpdateSecretCode(
            @RequestParam String phoneNum,
            @RequestParam String check_code) {
        if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(check_code)) {
            return R.error(1, "请正确填写手机号与验证码");
        }
        String key = MemberConstant.SMS_CODE_CACHE_PREFIX + phoneNum;
        if (!stringRedisTemplate.hasKey(key)) {
            return R.error(1, "验证码已过期，请重新获取");
        } else {
            String value = stringRedisTemplate.opsForValue().get(key);
            String code = value.split("_")[0];
            if (check_code.equals(code)) {
                stringRedisTemplate.delete(key);
                return R.ok();
            } else {
                return R.error(1, "验证码不正确");
            }
        }
    }

    /**
     * 更新密码
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/web/updateSecret")
    public R updateSecret(
            @RequestParam Long id,
            @RequestParam String old_password,
            @RequestParam String new_password) {
        MemberEntity member = memberService.getById(id);
        if (member == null) {
            return R.error(2, "未知错误，请重新登录");
        } else {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            if (!bCryptPasswordEncoder.matches(old_password, member.getPassword())) {
                return R.error(1, "请输入正确的原始密码，若忘记请点击忘记密码");
            } else {
                member.setPassword(bCryptPasswordEncoder.encode(new_password));
                memberService.updateById(member);
                RunTimeLog.printRunTimeLog(id + "号用户成功修改密码");
                return R.ok("修改成功");
            }
        }
    }


    /**
     * 远程接口。删除收货地址。如果是默认地址需要自动补位
     * 注意要做对应性验证
     *
     * @param id
     * @return
     */
    @ResponseBody
    @GetMapping("/web/deleteAddress")
    public R deleteAddress(@RequestParam Long id) {
        Long memberId = LoginInterceptor.loginUserThreadLocal.get().getId();
        MemberReceiveAddressEntity existedOne = memberReceiveAddressService.getOne(new QueryWrapper<MemberReceiveAddressEntity>()
                .eq("id", id)
                .eq("member_id", memberId));
        if(existedOne == null){
            return R.error(1, "你无法删除该收货地址，请重试");
        }
        if (existedOne.getDefaultStatus() == 0) {
            memberReceiveAddressService.removeById(id);
            return R.ok();
        } else {
            memberReceiveAddressService.removeById(id);
            List<MemberReceiveAddressEntity> addressLimit = memberReceiveAddressDao.getRandomLimit(memberId, 1);
            if (addressLimit != null && addressLimit.size() > 0) {
                MemberReceiveAddressEntity temp = addressLimit.get(0);
                temp.setDefaultStatus(1);
                memberReceiveAddressService.updateById(temp);
            }
            return R.ok();
        }
    }

    /**
     * 远程接口。设置选中地址为默认地址。原先默认地址降级
     * 注意要做对应性验证
     *
     * @param id
     * @return
     */
    @ResponseBody
    @GetMapping("/web/setToDefaultAddress")
    public R setToDefaultAddress(@RequestParam Long id) {
        Long memberId = LoginInterceptor.loginUserThreadLocal.get().getId();
        MemberReceiveAddressEntity targetOne = memberReceiveAddressService.getOne(new QueryWrapper<MemberReceiveAddressEntity>()
                .eq("id", id)
                .eq("member_id", memberId));
        if(targetOne == null){
            return R.error(1, "你无法修改这个收货地址");
        }
        // 原先的默认地址
        MemberReceiveAddressEntity existedOne = memberReceiveAddressService.getOne(new QueryWrapper<MemberReceiveAddressEntity>()
                .eq("member_id", memberId)
                .eq("default_status", 1));
        targetOne.setDefaultStatus(1);
        memberReceiveAddressService.updateById(targetOne);
        if(existedOne != null){
            existedOne.setDefaultStatus(0);
            memberReceiveAddressService.updateById(existedOne);
        }
        return R.ok();
    }


    /**
     * 远程接口。新增/修改 收货地址
     * @return
     */
    @ResponseBody
    @PostMapping("/web/addOrUpdateAddress")
    public R addOrUpdateAddress(@RequestBody MemberReceiveAddressTo memberReceiveAddressTo){
        Long memberId = LoginInterceptor.loginUserThreadLocal.get().getId();
        MemberReceiveAddressEntity entity = new MemberReceiveAddressEntity();
        BeanUtils.copyProperties(memberReceiveAddressTo, entity);
        entity.setMemberId(memberId);
        if(entity.getId() == null){
            memberReceiveAddressService.save(entity);
            return R.ok("添加成功");
        }else{
            memberReceiveAddressService.updateById(entity);
            return R.ok("修改成功");
        }
    }
}
